package global

import (
	"time"

	"github.com/pingcap/errors"
	"github.com/romberli/go-util/common"
	"github.com/romberli/go-util/http"
	"github.com/romberli/go-util/middleware/mysql"
	"github.com/romberli/log"
	"github.com/spf13/viper"

	"github.com/romberli/das/config"
)

const (
	defaultMaxIdleConns        = 200
	defaultMaxIdleConnsPerHost = 50
)

var (
	DASMySQLPool      *mysql.Pool
	HTTPClient        *http.Client
	HealthcheckBucket *common.Bucket
)

func InitDASMySQLPool() (err error) {
	dbAddr := viper.GetString(config.DBDASMySQLAddrKey)
	dbName := viper.GetString(config.DBDASMySQLNameKey)
	dbUser := viper.GetString(config.DBDASMySQLUserKey)
	dbPass := viper.GetString(config.DBDASMySQLPassKey)
	maxConnections := viper.GetInt(config.DBPoolMaxConnectionsKey)
	initConnections := viper.GetInt(config.DBPoolInitConnectionsKey)
	maxIdleConnections := viper.GetInt(config.DBPoolMaxIdleConnectionsKey)
	maxIdleTime := viper.GetInt(config.DBPoolMaxIdleTimeKey)
	maxWaitTime := viper.GetInt(config.DBPoolMaxWaitTimeKey)
	maxRetryCount := viper.GetInt(config.DBPoolMaxRetryCountKey)
	keepAliveInterval := viper.GetInt(config.DBPoolKeepAliveIntervalKey)

	cfg := mysql.NewConfig(dbAddr, dbName, dbUser, dbPass)
	poolConfig := mysql.NewPoolConfigWithConfig(cfg, maxConnections, initConnections, maxIdleConnections, maxIdleTime,
		maxWaitTime, maxRetryCount, keepAliveInterval)
	log.Debugf("pool config: %+v", poolConfig)
	DASMySQLPool, err = mysql.NewPoolWithPoolConfig(poolConfig)
	if err != nil {
		return errors.Errorf("create das mysql pool failed. addr: %s, db: %s, user: %s. error:\n%s",
			dbAddr, dbName, dbUser, err.Error())
	}

	return nil
}

func InitHTTPClient() (err error) {
	HTTPClient, err = http.NewClientWithRetry()
	if err != nil {
		return errors.Errorf("create http client failed. error:\n%s", err.Error())
	}

	HTTPClient.SetMaxIdleConns(defaultMaxIdleConns)
	HTTPClient.SetMaxIdleConns(defaultMaxIdleConnsPerHost)

	return nil
}

func InitHealthcheckBucket() (err error) {
	capacity := viper.GetInt(config.HealthCheckBucketCapacityKey)
	num := viper.GetInt(config.HealthCheckBucketNumKey)
	interval := viper.GetInt(config.HealthCheckBucketIntervalKey)

	HealthcheckBucket, err = common.NewBucket(capacity, num, time.Duration(interval)*time.Second)
	if err != nil {
		return errors.Errorf("create healthcheck bucket failed. error:\n%s", err.Error())
	}

	return nil
}
